import matplotlib
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.patches import Rectangle

# -------------------------------------------------
# 1️⃣  原始 2×2 像素块的 RGB 值（左上、右上、左下、右下）
# -------------------------------------------------
c00 = np.array([128, 64, 128])   # 左上 (0,0)
c10 = np.array([128, 64, 256])   # 右上 (1,0)
c01 = np.array([256, 64, 128])   # 左下 (0,1)
c11 = np.array([256, 64, 256])   # 右下 (1,1)

matplotlib.rcParams['font.family'] = 'Microsoft YaHei'  # Windows 常用

# -------------------------------------------------
# 2️⃣  双线性插值函数（对每个通道分别插值）
# -------------------------------------------------
def bilinear_interp(c00, c10, c01, c11, scale):
    """
    返回放大 scale 倍后的 RGB 矩阵，shape = (scale+1, scale+1, 3)
    """
    # 生成归一化坐标网格
    xs = np.linspace(0, 1, scale + 1)
    ys = np.linspace(0, 1, scale + 1)
    xv, yv = np.meshgrid(xs, ys, indexing='xy')   # (scale+1, scale+1)

    # 对每个通道做线性插值
    result = np.empty((scale + 1, scale + 1, 3), dtype=float)
    for ch in range(3):
        # 先在 x 方向插值
        ix = c00[ch] * (1 - xv) + c10[ch] * xv
        # 再在 y 方向插值
        result[..., ch] = ix * (1 - yv) + (c01[ch] * (1 - xv) + c11[ch] * xv) * yv
    return result

# -------------------------------------------------
# 3️⃣  生成 4 倍插值结果（得到 5×5 网格，实际像素是 4×4）
# -------------------------------------------------
scale = 4
interp_rgb = bilinear_interp(c00, c10, c01, c11, scale)   # shape (5,5,3)

# -------------------------------------------------
# 4️⃣  绘图函数
# -------------------------------------------------
def plot_interpolation(original, interp, scale):
    """
    original: 2×2×3 原始颜色矩阵
    interp:   (scale+1)×(scale+1)×3 插值后颜色矩阵
    """
    fig, ax = plt.subplots(figsize=(6, 6))
    ax.set_aspect('equal')
    ax.set_xlim(-0.5, scale + 0.5)
    ax.set_ylim(-0.5, scale + 0.5)
    ax.invert_yaxis()                     # y 轴向下为正（像素坐标习惯）




    # ---- 绘制放大后 4×4 像素块（每块大小 1×1，坐标从 0 到 4） ----
    for i in range(scale):
        for j in range(scale):
            # 取左上角的颜色作为该像素的显示颜色
            ij = interp[i, j]
            ij = np.clip(ij, 0, 255)
            color = ij / 255.0
            rect = Rectangle((j, i), 1, 1, facecolor=color, edgecolor='none')
            ax.add_patch(rect)

            ax.text(j + 0.5, i + 0.5,
                    f'({int(interp[i, j, 0])},{int(interp[i, j, 1])},{int(interp[i, j, 2])})',
                    ha='center', va='center', fontsize=8, color='white')

    # ---- 绘制网格线（帮助观察） ----
    ax.set_xticks(np.arange(-0.5, scale + 1, 1), minor=True)
    ax.set_yticks(np.arange(-0.5, scale + 1, 1), minor=True)
    ax.grid(which='minor', color='gray', linewidth=0.5, linestyle='--')

    # ---- 标注 ----
    ax.set_title(f'双线性插值放大 {scale} 倍示意图', fontsize=14)
    ax.set_xlabel('X')
    ax.set_ylabel('Y')
    plt.show()

# -------------------------------------------------
# 5️⃣  组织原始 2×2 矩阵并绘图
# -------------------------------------------------
original_rgb = np.stack([
    [c00, c10],
    [c01, c11]
])   # shape (2,2,3)

plot_interpolation(original_rgb, interp_rgb, scale)
